import * as pathToRegexp from 'path-to-regexp'

export let get = create('get');

function create(method) {
    if (method) method = method.toUpperCase();

    return function (path, fn, opts?) {
        const re = pathToRegexp(path, opts);

        const createRoute = function (routeFunc) {
            return function (ctx, next) {
                // method
                if (!matches(ctx, method)) return next();

                // path
                const m = re.exec(ctx.path);
                if (m) {
                    const args = m.slice(1).map(decode);
                    ctx.routePath = path;
                    return Promise.resolve(routeFunc.call(ctx, ctx, next, args));
                }
                // miss
                return next();
            }
        };

        if (fn) {
            return createRoute(fn);
        } else {
            return createRoute;
        }
    }
}

/**
 * Decode value.
 */

function decode(val) {
    if (val) return decodeURIComponent(val);
}

/**
 * Check request method.
 */

function matches(ctx, method) {
    if (!method) return true;
    if (ctx.method === method) return true;
    if (method === 'GET' && ctx.method === 'HEAD') return true;
    return false;
}
